﻿using System;
using System.Collections.Generic;
using System.ComponentModel.Composition.Hosting;
using ExcelAutomator.Configuration;
using log4net;

namespace ExcelAutomator
{
	public class ExecutorFactory
	{
		private readonly CompositionContainer m_Container;
		private readonly IDictionary<string, IList<Lazy<IExecutor, IExecutorMetadata>>> m_ExecutorsByType = new Dictionary<string, IList<Lazy<IExecutor, IExecutorMetadata>>>();

		public ExecutorFactory(CompositionContainer container)
		{
			m_Container = container;

			foreach (var executor in m_Container.GetExports<IExecutor, IExecutorMetadata>())
			{
				if (!m_ExecutorsByType.ContainsKey(executor.Metadata.Type))
				{
					m_ExecutorsByType.Add(executor.Metadata.Type, new List<Lazy<IExecutor, IExecutorMetadata>>(){executor});
				}
				else
				{
					m_ExecutorsByType[executor.Metadata.Type].Add(executor);
				}
			}
		}

		public bool TryCreate(ExecutorConfigurationWrapper cfg, out IExecutor executor)
		{
			if (cfg.Namespace.Equals(Constants.ExecutorExtensionsNamespace))
			{
				return UseDefaultResolver(cfg, out executor);
				//TODO Use custom Resolver
			}
			Log.Error(string.Format("Invalid namespace '{0}' for executor extensions.", cfg.Namespace));
			
			executor = null;
			return false;
		}

		private bool UseDefaultResolver(ExecutorConfigurationWrapper cfg, out IExecutor executor)
		{
			if (m_ExecutorsByType.ContainsKey(cfg.Type))
			{
				return ExecutorResolver.TryResolve(m_ExecutorsByType[cfg.Type], cfg, out executor);
			}
			executor = null;
			return false;
		}

		private static ILog Log
		{
			get { return LogManager.GetLogger(typeof (ExecutorFactory)); }
		}
	}
}
